/**
 * 
 */
package br.jus.tjpe.dao;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.Query;

import br.jus.tjpe.dominio.EntidadeBase;
import br.jus.tjpe.util.EntityManagerUtil;

/**
 * @author clebertmoura
 * 
 */
public class DaoGenerico<T extends EntidadeBase> {

	private EntityManagerUtil entityManagerUtil = EntityManagerUtil
			.getInstance();

	/**
	 * 
	 */
	public DaoGenerico() {
		// TODO Auto-generated constructor stub
	}
	
	/**
	 * @param entidade
	 * @return
	 * @throws PersistenceException
	 */
	public <E> E inserir(E entidade) throws PersistenceException {
		EntityManager entityManager = entityManagerUtil.getEntityManager();
		try {
			entityManager.getTransaction().begin();
			entityManager.persist(entidade);
			entityManager.getTransaction().commit();
		} finally {
			entityManager.close();
		}
		return entidade;
	}

	/**
	 * @param entidade
	 * @return
	 * @throws PersistenceException
	 */
	public <E> E editar(E entidade) throws PersistenceException {
		EntityManager entityManager = entityManagerUtil.getEntityManager();
		try {
			entityManager.getTransaction().begin();
			entidade = entityManager.merge(entidade);
			entityManager.getTransaction().commit();
		} finally {
			entityManager.close();
		}
		return entidade;
	}

	/**
	 * @param entidade
	 * @return
	 * @throws PersistenceException
	 */
	public <E> E remover(E entidade) throws PersistenceException {
		EntityManager entityManager = entityManagerUtil.getEntityManager();
		try {
			entityManager.getTransaction().begin();
			entidade = entityManager.merge(entidade);
			entityManager.remove(entidade);
			entityManager.getTransaction().commit();
		} finally {
			entityManager.close();
		}
		return entidade;
	}

	/**
	 * @param clazz
	 * @param id
	 * @return
	 * @throws PersistenceException
	 */
	public <E> E buscarPorId(Class<E> clazz, Serializable id)
			throws PersistenceException {
		EntityManager entityManager = entityManagerUtil.getEntityManager();
		E entidade = null;
		try {
			entidade = entityManager.find(clazz, id);
		} finally {
			entityManager.close();
		}
		return entidade;
	}

	/**
	 * @param clazz
	 * @return
	 * @throws PersistenceException
	 */
	@SuppressWarnings("unchecked")
	public List<T> buscarTodos() throws PersistenceException {
		EntityManager entityManager = entityManagerUtil.getEntityManager();
		List<T> list = new ArrayList<T>();
		try {
			Query query = entityManager.createQuery(String.format(
					"SELECT e FROM %s AS e", getClasseEntidade().getSimpleName()));
			list = query.getResultList();
		} finally {
			entityManager.close();
		}
		return list;
	}
	
	@SuppressWarnings("rawtypes")
	protected Class getClasseEntidade(){
		final ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();  
		return (Class) (type).getActualTypeArguments()[0]; 
	}
	
	protected EntityManager getEntityManager(){
		return entityManagerUtil.getEntityManager();
	}

}
